COP VS POP

软件架构关注对系统的分割和如何让分隔后的各部分交互,至于如何分割和如何交互,取决于对系统不同特性的关注程度的取舍。而不同的编程思想对架构的选型和建立影响很大。

编程思想

PO(Process Oriented)
面向过程:对业务的顺序的抽象,更关注流程的顺序

OO(Object Oriented)
面向对象:对业务的责任的抽象,更关注各个部分所承担的责任,也就是责任的划分。而架构关注系统的分割,两者都是关注与如何“化整为零”,所以设计架构时很容易就会采用OO的编程思想,即使语言设计之初时并没有考虑面向对象的JS也利用自己的特性实现了一种“非主流”的面向对象方式。

AO(Aspect Oriented)
面向切面:对业务的扩展性的抽象,更关注如何扩展、替换业务属性

SO (Service Oriented)
严格来说,SO并不属于编程思想,它针对的粒度更大,更关注业务的模块化、稳定性和部署要求

编程思想影响着架构设计,同时,不同的实现有不同的侧重点和易用性,语言本身对编程思想的实现也对架构设计影响不小。

下面就说说COP(Class Oriented Programming)和 POP(Protocol Oriented Programming)作为OO面向对象的两种实现,各自的优缺点。

COP?

COP(Class Oriented Programming),说白了就是以Class作为业务各个角色的模型,不同的角色拥有不同属性,体现在Class上就是不同的属性和方法。

COP非常强调身份:就是就是不是我们家族,具有强烈的“阶层意识”。于是在业务上,能够清晰地区分出角色的差异,也就是上面说的,专注于划分角色。

POP?

POP(Protocol Oriented Programming),说白了就是大家按照Protocol协议来做事,更强调角色的行为。

一个很形象的说明就是duck typing https://en.wikipedia.org/wiki/Duck_typing

When I see a bird that walks like a duck and swims like a duck and quacks like a duck, I call that bird a duck

相对来说,COP就是严格的typing。

COP VS POP

面向对象有三大特性:封装、继承、多态。下面就来看看两者对这三大特性的实现情况。

前面说的很大一部分都可以看做是封装上的区别:COP封装的是类型、角色,POP封装的是行为。

COP中,子类拥有一切父类的属性和方法,无论子类是否需要,对编程人员来说,很容易就无意地覆盖了父类的属性和方法,苹果自身的框架可以通过文档来说明,如果是自己的或者第三方的代码,就得沿着继承链挨个找,这就带来了额外的风险和负担;另外,每个子类的实例在初始化时除了初始化自身的属性和方法,还会把继承链上所有父类的属性方法都初始化一份,即使同名属性也一样,这显然会增大无谓的内存消耗。

POP中,你只需要实现所声明协议的属性和方法,不需要的付出额外的代价。

两者都能符合里氏替换原则,POP能以弱耦合的方式完成,而COP就会导致强耦合。

关于多态,其实,POP更倾向于使用组合代替继承,所以,尽量少用多态。

关于组合和继承,其实苹果也意识到这个问题,所以为OC实现了category的特性,的确避免了一部分“类爆炸”的问题。

Swift是第一门原生支持POP的语言,苹果的Swift标准库负责人 Dave Abrahams,在WWDC2015上历数了COP的几大罪状,感兴趣的可以看看:https://www.youtube.com/watch?v=g2LwFZatfTI,其中有两点我觉得有点“栽赃”的嫌疑:

  • implicit sharing:共享变量
  • lost type relations:丢失类型关联

我并不觉得共享变量是COP独有的问题,这个和是不是COP或者POP无关,严格来说,POP中的protocol也是一种类型,只不过是一种更“弱”的Class;同样,类型关联丢失也只是语法糖的问题。

POP对架构的助力

计算机发展初期,各大操作系统和硬件厂商都按照Class的方式来生产,带来了很大的市场推广阻力,因为各个系统不能互相通信。最终,通过制定操作系统和网络中的各种协议protocol,使得各种异构系统能够以弱耦合的方式相互交互和通信,这才为互联网的诞生奠定了基础。

协议的最大作用就在于弱化耦合关系,更多关注行为而非类型,这样我们才能专注实现需求。

POP弱化了静态语言的严格的类型检查,为语言增加了更大的动态性,同时也有利于降低内存消耗,对于移动开发具有一定优势,更重要的是它弱化了各个子系统的耦合,对于关注分割和交互的架构设计在解耦上有不错的效果。

坚持原创技术分享,您的支持将鼓励我继续创作!